package com.ruoyi.swla2.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.swla2.domain.PgFieldTableInfo;
import com.ruoyi.swla2.domain.PgRowInfo;
import com.ruoyi.swla2.domain.SysOss;
import com.ruoyi.swla2.service.IPgEditService;
import com.ruoyi.swla2.service.ISysOssService;
import com.ruoyi.swla2.util.MinioTemplate;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.parameters.P;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@RestController
@RequestMapping("/qtgis/pgedit")
public class PgEditController extends BaseController {
    @Autowired
    private IPgEditService iPgEditService;

    @Autowired
    private ISysOssService sysOssService;

    /**
     * 获取OSS文件列表
     *
     * @param tbl
     * @param id
     * @return
     */
    @GetMapping(value = "/getOssRecords")
    public AjaxResult getOssRecords(@RequestParam("tbl") String tbl, @RequestParam("id") String id) {
        PgFieldTableInfo pgFieldTableInfo = new PgFieldTableInfo();
        pgFieldTableInfo.setTableName("sys_oss");
        pgFieldTableInfo.setFields(Arrays.asList("target_table", "target_id"));
        pgFieldTableInfo.setPageNum(1);
        pgFieldTableInfo.setPageSize(99999);
        Map<String, Object> valueMap = new HashMap<>();
        valueMap.put("target_table", tbl);
        valueMap.put("target_id", id);
        pgFieldTableInfo.setFieldValues(valueMap);

        return iPgEditService.findNormalTableData(pgFieldTableInfo);
    }

    /**
     * 上传OSS文件
     */
    @PostMapping(value = "/uploadOss", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public AjaxResult uploadOss(@RequestPart MultipartFile file, @RequestParam("tbl") String tbl, @RequestParam("id") Long id, @RequestParam("type") Integer type) {
        SysOss sysOss = sysOssService.upload(file);
        sysOss.setTargetTable(tbl);
        sysOss.setTargetId(id);
        sysOss.setTargetType(type);
        sysOss.setCreateBy(this.getUsername());
        sysOss.setCreateTime(new Date());
        sysOss.setUpdateBy(this.getUsername());
        sysOss.setUpdateTime(new Date());
        sysOss.setService("minio");

        iPgEditService.addTableData(this.transformToPgRow("sys_oss", sysOss));
        return AjaxResult.success();
    }

    /**
     * 下载OSS对象
     */
    @GetMapping("/downloadOss")
    public void downloadOss(@RequestParam("fileName") String fileName, @RequestParam("originalName") String originalName, HttpServletResponse response) throws IOException {
        sysOssService.download(fileName, originalName, response);
    }

    /**
     * 删除OSS对象存储
     */
    @PostMapping("/removeOss")
    public AjaxResult removeOss(@RequestBody SysOss sysOss) {
        int result = sysOssService.remove(sysOss);
        return toAjax(result);
    }

    /**
     * 连接PostGIS本地数据库并获取表名
     *
     * @return 是否创建成功
     */
    @GetMapping(value = "/table")
    public AjaxResult getTableInfo() {
        return iPgEditService.getTableInfo();
    }

    /**
     * 连接PostGIS数据库并获取数据
     *
     * @return 是否创建成功
     */
    @PostMapping(value = "/data")
    public AjaxResult getTableData(@RequestBody PgFieldTableInfo pgFieldTableInfo) {
        System.out.println(JSON.toJSONString(pgFieldTableInfo));
        return pgFieldTableInfo.getTableType() == null || pgFieldTableInfo.getTableType() == 0 ? iPgEditService.getTableData(pgFieldTableInfo) : iPgEditService.findGisTableData(pgFieldTableInfo);
    }

    /**
     * 连接PostGIS数据库并查询表数据
     *
     * @return 是否创建成功
     */
    @PostMapping(value = "/find")
    public AjaxResult findTableData(@RequestBody PgFieldTableInfo pgFieldTableInfo) {
        System.out.println(JSON.toJSONString(pgFieldTableInfo));
        this.checkTenantId(pgFieldTableInfo);
        return pgFieldTableInfo.getTableType() == null || pgFieldTableInfo.getTableType() == 0 ? iPgEditService.findNormalTableData(pgFieldTableInfo) : iPgEditService.findGisTableData(pgFieldTableInfo);
    }

    /**
     * 添加数据
     *
     * @return 是否成功
     */
    @PostMapping(value = "/add")
    public AjaxResult addTableData(@RequestBody PgRowInfo pgRowInfo) {
        System.out.println(JSON.toJSONString(pgRowInfo));
        this.checkRowGeom(pgRowInfo);
        if (pgRowInfo.getTableType() == 0) {
            pgRowInfo.getFields().add("tenant_id");
            pgRowInfo.getNewRow().put("tenant_id", this.getTenantId());
        }
        return iPgEditService.addTableData(pgRowInfo);
    }

    /**
     * 更新数据
     *
     * @return 是否成功
     */
    @PostMapping(value = "/update")
    public AjaxResult updateTableData(@RequestBody PgRowInfo pgRowInfo) {
        System.out.println(JSON.toJSONString(pgRowInfo));
        this.checkRowGeom(pgRowInfo);
//        System.out.println(JSON.toJSONString(params)); @RequestBody Map<String, Object> params
//        String tableName = MapUtil.getStr(params, "tableName");
//        Long id = MapUtil.getLong(params, "id");
//        Integer type = MapUtil.getInt(params, "type");

//        String tableName = pgRowInfo.getTableName();
//        Long id = pgRowInfo.getId();
//        Integer type = pgRowInfo.getTableType();
//
        this.checkTimestampFields(pgRowInfo.getTableType(), pgRowInfo.getNewRow());
//        params.remove("tableName");
//        params.remove("id");
//        params.remove("type");

        System.out.println(JSON.toJSONString(pgRowInfo));
        return iPgEditService.updateTableData(pgRowInfo);
//        return success();
    }

    /**
     * 删除数据
     *
     * @return 是否成功
     */
    @PostMapping(value = "/delete")
    public AjaxResult deleteTableData(@RequestBody PgRowInfo pgRowInfo) {
        this.checkRowGeom(pgRowInfo);
        return iPgEditService.deleteTableData(pgRowInfo);
    }

    /**
     * 添加管点数据
     *
     * @return 是否成功
     */
    @PostMapping(value = "/addPoint")
    public AjaxResult addPointTableData(@RequestBody PgRowInfo pgRowInfo) {
        System.out.println(JSON.toJSONString(pgRowInfo));
        this.checkRowGeom(pgRowInfo);
        this.checkTimestampFields(pgRowInfo.getTableType(), pgRowInfo.getNewRow());
        return iPgEditService.addPointTableData(pgRowInfo);
    }

    /**
     * 更新管点数据
     *
     * @return 是否成功
     */
    @PostMapping(value = "/updatePoint")
    public AjaxResult updatePointTableData(@RequestBody PgRowInfo pgRowInfo) {
        System.out.println(JSON.toJSONString(pgRowInfo));
        this.checkRowGeom(pgRowInfo);
        this.checkTimestampFields(pgRowInfo.getTableType(), pgRowInfo.getNewRow());
        return iPgEditService.updatePointTableData(pgRowInfo);
    }

    /**
     * 添加管线数据
     *
     * @return 是否成功
     */
    @PostMapping(value = "/addLine")
    public AjaxResult addLineTableData(@RequestBody PgRowInfo pgRowInfo) {
        System.out.println(JSON.toJSONString(pgRowInfo));
        this.checkRowGeom(pgRowInfo);
        this.checkTimestampFields(pgRowInfo.getTableType(), pgRowInfo.getNewRow());
        return iPgEditService.addLineTableData(pgRowInfo);
    }

    /**
     * 更新管线数据
     *
     * @return 是否成功
     */
    @PostMapping(value = "/updateLine")
    public AjaxResult updateLineTableData(@RequestBody PgRowInfo pgRowInfo) {
        System.out.println(JSON.toJSONString(pgRowInfo));
        this.checkRowGeom(pgRowInfo);
        this.checkTimestampFields(pgRowInfo.getTableType(), pgRowInfo.getNewRow());
        return iPgEditService.updateLineTableData(pgRowInfo);
    }

    @Anonymous
    @GetMapping(value = "/testOss")
    public AjaxResult testOss() {
        SysOss sysOss = new SysOss();
        sysOss.setTargetTable("wuchuan_line");
        sysOss.setTargetId(10L);
        sysOss.setTargetType(2);
        sysOss.setFileName("2023/12/06/9db1bc3f267e4e2d83c67dc40c0128ae.png");
        sysOss.setOriginalName("ops1.png");
        sysOss.setFileSuffix(".png");
        sysOss.setUrl("http://218.92.234.138:9000/bzxt/2023/12/06/9db1bc3f267e4e2d83c67dc40c0128ae.png");
        sysOss.setCreateBy("admin");
        sysOss.setCreateTime(new Date());
        sysOss.setUpdateBy("admin");
        sysOss.setUpdateTime(new Date());
        sysOss.setService("minio");

        return iPgEditService.addTableData(this.transformToPgRow("sys_oss", sysOss));
    }

    private void checkTimestampFields(Integer type, Map<String, Object> params) {
        List<String> filedList = new ArrayList<>();
        if (type == 0) { //
            filedList.add("create_time");
            filedList.add("update_time");
        } else if (type == 1) { //
            filedList.add("MDATE");
            filedList.add("SUR_DATE");
            filedList.add("DB_DATE");
        } else if (type == 2) {
            filedList.add("MDATE");
            filedList.add("SUR_DATE");
            filedList.add("DB_DATE");
        }

        if (CollUtil.isNotEmpty(filedList)) {
            filedList.forEach(field -> {
                String val = MapUtil.getStr(params, field);
                if (StrUtil.isNotEmpty(val)) {
                    params.put(field, DateUtil.parseDate(val));
                }
            });
        }
    }

    private PgRowInfo transformToPgRow(String tableName, Object origin) {
        return this.transformToPgRow(tableName, origin, true);
    }

    private PgRowInfo transformToPgRow(String tableName, Object origin, boolean isToUnderlineCase) {
        return this.transformToPgRow(tableName, origin, isToUnderlineCase, false);
    }

    private PgRowInfo transformToPgRow(String tableName, Object origin, boolean isToUnderlineCase, boolean ignoreNullValue) {
        PgRowInfo result = new PgRowInfo();
        result.setTableName(tableName);
        Map<String, Object> newRowMap = BeanUtil.beanToMap(origin, isToUnderlineCase, ignoreNullValue);
        result.setNewRow(newRowMap);
        result.setFields(new ArrayList<>(newRowMap.keySet()));

        return result;
    }

    private void checkTenantId(PgFieldTableInfo pgFieldTableInfo) {
        if (pgFieldTableInfo.getFields() == null) {
            pgFieldTableInfo.setFields(new ArrayList<>());
        }
        if (pgFieldTableInfo.getFieldValues() == null) {
            pgFieldTableInfo.setFieldValues(new HashMap<>());
        }
        pgFieldTableInfo.getFields().add("tenant_id");
        pgFieldTableInfo.getFieldValues().put("tenant_id", this.getTenantId());
    }

    private void checkRowGeom(PgRowInfo row) {
        if (StrUtil.isEmpty(row.getGeom())) {
            row.setGeom("geom");
        }
    }

    public static void main(String[] args) {
        System.out.println(UUID.randomUUID().toString().replace("-", ""));
    }
}
